Raw Eventsを使って未キャッシュのデータも処理する
Discord.js v11以前では、キャッシュされていないデータをイベントで受け取る専用の方法(partial)がなかった 文字通り生のデータだから決して扱いやすいわけではなく比較的複雑なDiscord APIのドキュメントを見る必要もあるので、可能ならv12で追加されたpartialを使うか、事前にfetchしておくなどの別の方法で代替したほうが良いかも知れない code:js
client.on('raw', packet => {
// We don't want this to run on unrelated packets
// Grab the channel to check the message from
const channel = client.channels.get(packet.d.channel_id);
// There's no need to emit if the message is cached, because the event will fire anyway for that
if (channel.messages.has(packet.d.message_id)) return;
// Since we have confirmed the message is not cached, let's fetch it
channel.fetchMessage(packet.d.message_id).then(message => {
// Emojis can have identifiers of name:id format, so we have to account for that case as well
const emoji = packet.d.emoji.id ? ${packet.d.emoji.name}:${packet.d.emoji.id} : packet.d.emoji.name;
// This gives us the reaction we need to emit the event properly, in top of the message object
const reaction = message.reactions.get(emoji);
// Adds the currently reacting user to the reaction's users collection.
if (reaction) reaction.users.set(packet.d.user_id, client.users.get(packet.d.user_id));
// Check which type of event it is before emitting
if (packet.t === 'MESSAGE_REACTION_ADD') {
client.emit('messageReactionAdd', reaction, client.users.get(packet.d.user_id));
}
if (packet.t === 'MESSAGE_REACTION_REMOVE') {
client.emit('messageReactionRemove', reaction, client.users.get(packet.d.user_id));
}
});
});